package ar.edu.itba.pod.legajo45129.simul.simulation;

import java.rmi.RemoteException;
import java.util.Collection;

import org.apache.log4j.Logger;

import ar.edu.itba.pod.simul.communication.ConnectionManager;
import ar.edu.itba.pod.simul.communication.NodeAgentLoad;
import ar.edu.itba.pod.simul.local.LocalSimulation;
import ar.edu.itba.pod.simul.simulation.Agent;
import ar.edu.itba.pod.simul.simulation.SimulationInspector;
import ar.edu.itba.pod.simul.simulation.SimulationManager;
import ar.edu.itba.pod.simul.time.TimeMapper;

import com.google.common.base.Preconditions;

public class SimulationManagerImpl implements SimulationManager {
	private ConnectionManager connectionManager;
	private LocalSimulation localSimulation;
	private static Logger logger = Logger.getLogger(SimulationManagerImpl.class);

	public SimulationManagerImpl(ConnectionManager connectionManager, TimeMapper timeMapper) {
		this.connectionManager = connectionManager;
		localSimulation = new LocalSimulation(timeMapper);
	}

	@Override
	public void addAgent(Agent agent) {
//		localSimulation.addAgent(agent);
		try {
			NodeAgentLoad minimiumNodeKnownLoad = connectionManager.getSimulationCommunication().getMinimumNodeKnownLoad();
			logger.debug("add agent " + agent.getName() + " to: " + minimiumNodeKnownLoad.getNodeId());
			connectionManager.getConnectionManager(minimiumNodeKnownLoad.getNodeId())
					.getSimulationCommunication().startAgent(agent.getAgentDescriptor());
		} catch (RemoteException e) {
			logger.error("addAgent error: " + e.getMessage());
			return;
		}
		logger.debug("agent: " + agent.getName() + " added");
	}

	@Override
	public Collection<Agent> getAgents() {
		return localSimulation.getAgents();
	}

	@Override
	public SimulationInspector inspector() {
		return simulation();
	}

	@Override
	public <T> void register(Class<T> type, T instance) {
		localSimulation.register(type, instance);
		logger.debug("type: " + type + " registered");
	}

	@Override
	public void removeAgent(Agent agent) {
		localSimulation.remove(agent);
		logger.debug("agent: " + agent.getName() + " removed");
		
	}

	@Override
	public void shutdown() {
		localSimulation.shutdown();
		logger.info("simulation shut down");
		
	}

	@Override
	public LocalSimulation simulation() {
		Preconditions.checkNotNull(localSimulation);
		return localSimulation;
	}

	@Override
	public void start() {
		localSimulation.start();
		logger.info("Simulation started");
		
	}
}
